package com.server.questionbank.snframe.util.FileUtil.operation.multipart.chunk;

import io.minio.GetObjectArgs;
import io.minio.MinioClient;
import lombok.extern.slf4j.Slf4j;

import java.io.InputStream;
import java.io.RandomAccessFile;
import java.util.concurrent.Callable;

/**
 * 分片下载操作
 * 处理单个分片的下载，并写入到指定位置
 */
@Slf4j
public class DownloadChunkOperation implements Callable<Void> {
    /** MinIO客户端 */
    private final MinioClient minioClient;
    /** 存储桶名称 */
    private final String bucket;
    /** 对象名称 */
    private final String object;
    /** 目标文件的随机访问对象 */
    private final RandomAccessFile raf;
    /** 分片起始位置 */
    private final long offset;
    /** 分片长度 */
    private final long length;
    /** 分片号 */
    private final int partNumber;

    public DownloadChunkOperation(MinioClient minioClient, String bucket, String object,
            RandomAccessFile raf, long offset, long length, int partNumber) {
        this.minioClient = minioClient;
        this.bucket = bucket;
        this.object = object;
        this.raf = raf;
        this.offset = offset;
        this.length = length;
        this.partNumber = partNumber;
    }

    @Override
    public Void call() throws Exception {
        log.debug("开始下载分片: bucket={}, object={}, partNumber={}, offset={}, length={}", 
            bucket, object, partNumber, offset, length);
            
        try (InputStream is = minioClient.getObject(
            GetObjectArgs.builder()
                .bucket(bucket)
                .object(object)
                .offset(offset)
                .length(length)
                .build()
        )) {
            // 同步写入文件，确保线程安全
            synchronized (raf) {
                raf.seek(offset);
                byte[] buffer = new byte[8192];
                int bytesRead;
                long totalRead = 0;
                
                while ((bytesRead = is.read(buffer)) != -1) {
                    raf.write(buffer, 0, bytesRead);
                    totalRead += bytesRead;
                }
                
                log.debug("分片下载完成: bucket={}, object={}, partNumber={}, totalBytes={}", 
                    bucket, object, partNumber, totalRead);
            }
            return null;
        }
    }
} 